package com.tfswue.lhj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tfswue.lhj.common.PageQuery;
import com.tfswue.lhj.constant.Constants;
import com.tfswue.lhj.dto.UserDTO;
import com.tfswue.lhj.entity.User;
import com.tfswue.lhj.mapper.UserMapper;
import com.tfswue.lhj.service.UserService;
import com.tfswue.lhj.util.DateUtil;
import com.tfswue.lhj.vo.UserVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 * 
 * @author daygods
 * @since 2025-07-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
    private final PasswordEncoder passwordEncoder;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean register(UserDTO userDTO) {
        // 检查用户名是否已存在
        if (existsUsername(userDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (StringUtils.hasText(userDTO.getEmail()) && existsEmail(userDTO.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        user.setStatus(Constants.USER_STATUS_NORMAL);
        user.setLoginCount(0);
        user.setDeleted(false);
        
        return save(user);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVO login(String username, String password, String loginIp) {
        User user = findByUsername(username);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        if (!user.isNormal()) {
            throw new RuntimeException("用户已被禁用");
        }
        
        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        
        // 更新登录信息
        baseMapper.updateLoginInfo(user.getId(), loginIp, LocalDateTime.now(), user.getLoginCount() + 1);
        
        // 转换为VO
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setPassword(null); // 不返回密码
        
        return userVO;
    }
    
    @Override
    public User findByUsername(String username) {
        return baseMapper.findByUsername(username);
    }
    
    @Override
    public User findByEmail(String email) {
        return baseMapper.findByEmail(email);
    }
    
    @Override
    public IPage<UserVO> getUserPage(PageQuery pageQuery) {
        Page<User> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
        
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(pageQuery.getKeyword())) {
            wrapper.and(w -> w.like(User::getUsername, pageQuery.getKeyword())
                    .or().like(User::getNickname, pageQuery.getKeyword())
                    .or().like(User::getEmail, pageQuery.getKeyword()));
        }
        
        wrapper.orderByDesc(User::getCreateTime);
        
        IPage<User> userPage = page(page, wrapper);
        
        // 转换为VO
        IPage<UserVO> voPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<UserVO> voList = userPage.getRecords().stream().map(user -> {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            vo.setPassword(null);
            return vo;
        }).collect(Collectors.toList());
        voPage.setRecords(voList);
        
        return voPage;
    }
    
    @Override
    public UserVO getUserById(Long userId) {
        User user = getById(userId);
        if (user == null) {
            return null;
        }
        
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        userVO.setPassword(null);
        
        return userVO;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createUser(UserDTO userDTO) {
        return register(userDTO);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(Long userId, UserDTO userDTO) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户名是否已被其他用户使用
        if (!user.getUsername().equals(userDTO.getUsername()) && existsUsername(userDTO.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否已被其他用户使用
        if (StringUtils.hasText(userDTO.getEmail()) && 
            !userDTO.getEmail().equals(user.getEmail()) && existsEmail(userDTO.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        BeanUtils.copyProperties(userDTO, user, "id", "password", "createTime", "loginCount", "lastLoginTime", "lastLoginIp");
        
        return updateById(user);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        return removeById(userId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserStatus(Long userId, Integer status) {
        return baseMapper.updateUserStatus(userId, status) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(Long userId, String newPassword) {
        String encodedPassword = passwordEncoder.encode(newPassword);
        return baseMapper.updateUserPassword(userId, encodedPassword) > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }
        
        String encodedPassword = passwordEncoder.encode(newPassword);
        return baseMapper.updateUserPassword(userId, encodedPassword) > 0;
    }
    
    @Override
    public boolean existsUsername(String username) {
        return baseMapper.existsUsername(username, null);
    }
    
    @Override
    public boolean existsEmail(String email) {
        return baseMapper.existsEmail(email, null);
    }
    
    @Override
    public List<UserVO> getRecentLoginUsers(int limit) {
        List<User> users = baseMapper.getRecentLoginUsers(limit);
        return users.stream().map(user -> {
            UserVO vo = new UserVO();
            BeanUtils.copyProperties(user, vo);
            vo.setPassword(null);
            return vo;
        }).collect(Collectors.toList());
    }
}
